package com.och.mrcp.core.rtp.session;

import com.och.mrcp.config.RtpConfig;
import com.och.mrcp.core.rtp.model.RtpPacket;
import com.och.mrcp.handler.VoiceRecognitionSessionHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * RTP会话管理器
 * 专注于管理RTP会话的生命周期和资源分配
 * 语音识别相关功能由专门的处理器负责
 */
@Slf4j
@Component
public class RtpSessionManager {
    
    // 会话存储
    private final Map<String, RtpSession> sessions = new ConcurrentHashMap<>();
    private final Map<InetSocketAddress, String> addressToSession = new ConcurrentHashMap<>();
    
    // 会话ID生成器
    private final AtomicInteger sessionIdCounter = new AtomicInteger(1);
    
    // 语音识别处理器
    @Lazy
    @Autowired
    private VoiceRecognitionSessionHandler voiceRecognitionHandler;
    
    // RTP配置
    @Autowired
    private RtpConfig rtpConfig;
    
    // 定时任务执行器 - 优化为多线程调度器
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(4, r -> {
        Thread t = new Thread(r, "RtpSessionManager-Scheduler");
        t.setDaemon(true);
        return t;
    });
    
    // 配置参数
    private static final long SESSION_TIMEOUT_MS = 30000; // 30秒超时
    private static final long CLEANUP_INTERVAL_MS = 10000; // 10秒清理一次
    
    public RtpSessionManager() {
        // 启动定时清理任务
        startCleanupTask();
    }
    
    /**
     * 创建新的RTP会话
     */
    public RtpSession createSession(InetSocketAddress localAddress, InetSocketAddress remoteAddress) {
        String sessionId = generateSessionId();
        
        RtpSession session = new RtpSession(sessionId, localAddress, remoteAddress, rtpConfig);
        
        // 设置语音识别处理器
        if (voiceRecognitionHandler != null) {
            session.setVoiceRecognitionHandler(voiceRecognitionHandler);
            log.debug("Voice recognition handler set for RTP session: {}", sessionId);
        } else {
            log.warn("Voice recognition handler not available for RTP session: {}", sessionId);
        }
        
        sessions.put(sessionId, session);
        addressToSession.put(remoteAddress, sessionId);
        
        log.info("RTP session created: {} -> {}:{} with RTP config", 
                localAddress, remoteAddress.getAddress().getHostAddress(), remoteAddress.getPort());
        
        return session;
    }
    
    /**
     * 根据会话ID获取会话
     */
    public RtpSession getSession(String sessionId) {
        return sessions.get(sessionId);
    }
    
    /**
     * 根据远程地址获取会话
     */
    public RtpSession getSessionByRemoteAddress(InetSocketAddress remoteAddress) {
        String sessionId = addressToSession.get(remoteAddress);
        return sessionId != null ? sessions.get(sessionId) : null;
    }
    
    /**
     * 启动会话
     */
    public boolean startSession(String sessionId) {
        RtpSession session = sessions.get(sessionId);
        if (session != null) {
            session.start();
            log.info("RTP session started: {}", sessionId);
            return true;
        }
        log.warn("RTP session not found: {}", sessionId);
        return false;
    }
    
    /**
     * 暂停会话
     */
    public boolean pauseSession(String sessionId) {
        RtpSession session = sessions.get(sessionId);
        if (session != null) {
            session.pause();
            log.info("RTP session paused: {}", sessionId);
            return true;
        }
        log.warn("RTP session not found: {}", sessionId);
        return false;
    }
    
    /**
     * 恢复会话
     */
    public boolean resumeSession(String sessionId) {
        RtpSession session = sessions.get(sessionId);
        if (session != null) {
            session.resume();
            log.info("RTP session resumed: {}", sessionId);
            return true;
        }
        log.warn("RTP session not found: {}", sessionId);
        return false;
    }
    
    /**
     * 终止会话
     */
    public boolean terminateSession(String sessionId) {
        RtpSession session = sessions.get(sessionId);
        if (session != null) {
            session.terminate();
            
            // 从映射中移除
            sessions.remove(sessionId);
            addressToSession.remove(session.getRemoteAddress());
            
            log.info("RTP session terminated: {}", sessionId);
            return true;
        }
        log.warn("RTP session not found: {}", sessionId);
        return false;
    }
    
    /**
     * 终止会话并通知回调
     */
    public boolean terminateSession(String sessionId, Runnable onSessionEnd) {
        RtpSession session = sessions.get(sessionId);
        if (session != null) {
            session.terminate();
            
            // 通知会话结束
            if (onSessionEnd != null) {
                onSessionEnd.run();
            }
            
            // 从映射中移除
            sessions.remove(sessionId);
            addressToSession.remove(session.getRemoteAddress());
            
            log.info("RTP session terminated: {}", sessionId);
            return true;
        }
        log.warn("RTP session not found: {}", sessionId);
        return false;
    }
    
    /**
     * 处理接收到的RTP包
     */
    public void handleRtpPacket(InetSocketAddress remoteAddress, byte[] packetData) {
        RtpSession session = getSessionByRemoteAddress(remoteAddress);
        if (session == null) {
            log.warn("No RTP session found for remote address: {}", remoteAddress);
            return;
        }
        
        try {
            // 解析RTP包
            RtpPacket packet = RtpPacket.parse(packetData);
            
            // 处理包
            session.handleReceivedPacket(packet);
            
        } catch (Exception e) {
            log.error("Error handling RTP packet from {}: {}", remoteAddress, e.getMessage(), e);
        }
    }
    
    /**
     * 获取会话统计信息
     */
    public RtpSessionStats getSessionStats(String sessionId) {
        RtpSession session = sessions.get(sessionId);
        return session != null ? session.getStats() : null;
    }
    
    /**
     * 获取所有会话的统计信息
     */
    public Map<String, RtpSessionStats> getAllSessionStats() {
        Map<String, RtpSessionStats> stats = new ConcurrentHashMap<>();
        sessions.forEach((id, session) -> stats.put(id, session.getStats()));
        return stats;
    }
    
    /**
     * 获取活跃会话数量
     */
    public int getActiveSessionCount() {
        return (int) sessions.values().stream()
                .filter(RtpSession::isActive)
                .count();
    }
    
    /**
     * 获取总会话数量
     */
    public int getTotalSessionCount() {
        return sessions.size();
    }
    
    /**
     * 生成会话ID
     */
    private String generateSessionId() {
        return "rtp-" + System.currentTimeMillis() + "-" + sessionIdCounter.getAndIncrement();
    }
    
    /**
     * 启动定时清理任务
     */
    private void startCleanupTask() {
        scheduler.scheduleAtFixedRate(this::cleanupExpiredSessions, 
                CLEANUP_INTERVAL_MS, CLEANUP_INTERVAL_MS, TimeUnit.MILLISECONDS);
        log.info("RTP session cleanup task started");
    }
    
    /**
     * 清理过期的会话
     */
    private void cleanupExpiredSessions() {
        long currentTime = System.currentTimeMillis();
        
        sessions.entrySet().removeIf(entry -> {
            RtpSession session = entry.getValue();
            InetSocketAddress remoteAddress = session.getRemoteAddress();
            
            // 检查会话是否超时
            if (currentTime - session.getLastActivityTime().get() > SESSION_TIMEOUT_MS) {
                log.info("Cleaning up expired RTP session: {}", entry.getKey());
                
                // 终止会话
                session.terminate();
                
                // 从地址映射中移除
                addressToSession.remove(remoteAddress);
                
                return true; // 从会话映射中移除
            }
            
            return false;
        });
    }
    
    /**
     * 为现有会话设置语音识别处理器
     */
    public void setVoiceRecognitionHandlerForExistingSessions() {
        if (voiceRecognitionHandler == null) {
            log.warn("Voice recognition handler not available");
            return;
        }
        
        int updatedCount = 0;
        for (RtpSession session : sessions.values()) {
            session.setVoiceRecognitionHandler(voiceRecognitionHandler);
            updatedCount++;
        }
        
        log.info("Voice recognition handler set for {} existing RTP sessions", updatedCount);
    }
    
    /**
     * 获取服务信息
     */
    public String getServiceInfo() {
        return String.format("RtpSessionManager{totalSessions=%d, activeSessions=%d, cleanupInterval=%dms, sessionTimeout=%dms}",
            sessions.size(), getActiveSessionCount(), CLEANUP_INTERVAL_MS, SESSION_TIMEOUT_MS);
    }
    
    /**
     * 清理所有会话
     */
    public void cleanupAllSessions() {
        log.info("Cleaning up all RTP sessions: {}", sessions.size());
        
        sessions.forEach((sessionId, session) -> {
            try {
                session.terminate();
                log.debug("Cleaned up RTP session: {}", sessionId);
            } catch (Exception e) {
                log.warn("Error cleaning up RTP session: {}", sessionId, e);
            }
        });
        
        sessions.clear();
        addressToSession.clear();
        
        log.info("All RTP sessions cleaned up");
    }
    
    /**
     * 关闭管理器
     */
    public void shutdown() {
        log.info("Shutting down RTP Session Manager...");
        
        // 清理所有会话
        cleanupAllSessions();
        
        // 关闭定时任务
        scheduler.shutdown();
        try {
            if (!scheduler.awaitTermination(10, TimeUnit.SECONDS)) {
                scheduler.shutdownNow();
            }
        } catch (InterruptedException e) {
            scheduler.shutdownNow();
            Thread.currentThread().interrupt();
        }
        
        log.info("RTP Session Manager shutdown completed");
    }
}
